﻿using System;
using System.ServiceModel;
using System.Threading;
using SLS.ExClassLib;
using SLS.ExClassLib.ExThreading;
using SLS.ExClassLib.Message;
using SLS.ExClassLib.SingleAgent;
using SLS.Core.HLASimu;
namespace SLS.Core.SingleAgent
{
    /// <summary>
    /// Implementation of the callback contract.
    /// </summary>
    public class SAAgent
    {
        public SingleAgentServiceClient SAClient;
        private InstanceContext instanceContext;
        private string m_Address;
        public string Address
        {
            get { return m_Address; }
            set { m_Address = value; }
        }
        public SAAgent()
        {
            SingleAgentCallback chatServiceCallback = new SingleAgentCallback();
            chatServiceCallback.ClientNotified += ChatServiceCallback_ClientNotified;
            instanceContext = new InstanceContext(chatServiceCallback);
            SAClient = new SingleAgentServiceClient(instanceContext, "TcpBinding"); 
            try
            {
                MessageEx msgRequest = new MessageEx();
                m_Address = "SA" + Guid.NewGuid().ToString().ToUpper();
                msgRequest.Address = m_Address;
                msgRequest.JobID = "OnJoinFederation";
                SAClient.SendSAMessage(msgRequest);
            }
            catch (Exception ex)
            {
                //throw;
            }
        }
        private void ChatServiceCallback_ClientNotified(object sender, ClientNotifiedEventArgs e)
        {

        }
    }
    [CallbackBehavior(
    ConcurrencyMode = ConcurrencyMode.Single,
    UseSynchronizationContext = false)]
    public class SingleAgentCallback : SingleAgentServiceCallback
    {
        public event ClientNotifiedEventHandler ClientNotified;
        public SynchronizationContext _uiSyncContext = null;
        public WorkQueue work;
        public delegate void SafeWinFormsThreadDelegate(MessageEx msg);
        public SingleAgentCallback()
        {
            _uiSyncContext = SynchronizationContext.Current;
            work = new WorkQueue();
            work.ConcurrentLimit = 1;
            ((WorkThreadPool)work.WorkerPool).MaxThreads = 1;
            work.AllWorkCompleted += new EventHandler(work_AllWorkCompleted);
            work.WorkerException += new ResourceExceptionEventHandler(work_WorkerException);
            work.ChangedWorkItemState += new ChangedWorkItemStateEventHandler(work_ChangedWorkItemState);
        }
        private void BuildWorkQueue(MessageEx This_Message)
        {
            ExWorkItem ThisWorkItem =
                new ExWorkItem(This_Message, null);

            work.Add(ThisWorkItem);
        }
        private void work_ChangedWorkItemState(object sender, ChangedWorkItemStateEventArgs e)
        {
            lock (this)
            {
                ExWorkItem exWinWI = (ExWorkItem)e.WorkItem;
                MessageEx msg = exWinWI.ThisMessage;
                WorkItemState state = exWinWI.State;
                if (state == WorkItemState.Completed)
                {
                    if (ClientNotified != null)
                    {
                        ClientNotified(this, new ClientNotifiedEventArgs(msg));
                    }
                }
            }
        }
        private void work_AllWorkCompleted(object sender, EventArgs e)
        {
            /*
            if (this.Dispatcher.CheckAccess())
            {
                this.Dispatcher.BeginInvoke(new EventHandler(work_AllWorkCompleted), new object[] { sender, e });
            }
            else
            {
                Cursor = Cursors.Arrow;
            }
            */

        }
        private void work_WorkerException(object sender, ResourceExceptionEventArgs ex)
        {
            //throw;
        }
        /// <summary> 
        /// Notifies the client of the message by raising an event. 
        /// </summary> 
        /// <param name="message">Message from the server.</param>
        [CLSCompliantAttribute(false)]
        public void HandleSAMessage(MessageEx msgRequest)
        {
            string AgentID = msgRequest.AgentID;
            SendOrPostCallback callback =
                delegate(object state)
                { this.BuildWorkQueue(msgRequest); };
            _uiSyncContext.Post(callback, AgentID);
        }
    }
    public delegate void ClientNotifiedEventHandler(object sender, ClientNotifiedEventArgs e);

    /// <summary> 
    /// Custom event arguments. 
    /// </summary> 
    public class ClientNotifiedEventArgs : EventArgs
    {
        private readonly MessageEx msgRequest;
        /// <summary> 
        /// Constructor. 
        /// </summary> 
        /// <param name="message">Message from server.</param>
        public ClientNotifiedEventArgs(MessageEx msg)
        {
            this.msgRequest = msg;
        }
        /// <summary>
        /// Gets the message.
        /// </summary> 
        public MessageEx Message
        {
            get
            {
                return msgRequest;
            }
        }
    }
}
